#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from typing import Optional, NoReturn,List
from loguru import logger
from datetime import datetime

from sqlalchemy import func, select, update, delete, desc
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy.sql import Select

from app.api import jwt
from app.models import User
from app.models import Task

from app.schemas.user import CreateUser, DeleteUser, UpdateUser
from app.schemas.task import DAOCreateTask

from app.utils.script_powershell import login_by_powershell 


async def get_all_task(db: AsyncSession) -> List[Task]:
    tasks = await db.execute(select(Task))
    return tasks.scalars().all()

async def get_task_by_name(db: AsyncSession, name: str) -> Optional[Task]:
    task = await db.execute(select(Task).where(Task.name == name))
    return task.scalars().first()

async def create_task(db: AsyncSession,task:DAOCreateTask ) -> NoReturn:
    new_task = Task(**task.dict())
    db.add(new_task)
    await db.commit()


async def delete_task_by_task_name(db: AsyncSession, task_name: str) -> int:
    task = await db.execute(delete(Task).where(Task.task_name == task_name))
    return task.rowcount


# -------------------------


async def get_task_by_task_name(db: AsyncSession, task_name:str) -> Optional[User]:
    user = await db.execute(select(Task).where(Task.task_name == task_name))
    return user.scalars().first()


async def get_user_by_loginid(db: AsyncSession, loginid: str) -> Optional[User]:
    user = await db.execute(select(User).where(User.loginid == loginid))
    return user.scalars().first()


# update time每次要手动更新,
async def update_task_user_name_by_id(db: AsyncSession, id: int,name:str) -> int:
    user = await db.execute(
        update(Task)
        .where(Task.id == id)
        .values({
            Task.name:name
        })
    )
    await db.commit()
    return user.rowcount


async def get_email_by_username(db: AsyncSession, username: str) -> str:
    user = await get_user_by_loginid(db, username)
    return user.email


async def get_username_by_email(db: AsyncSession, email: str) -> str:
    user = await db.execute(select(User).where(User.email == email))
    return user.scalars().first().username


async def get_avatar_by_username(db: AsyncSession, username: str) -> str:
    user = await db.execute(select(User).where(User.username == username))
    return user.scalars().first().avatar


# async def create_user(db: AsyncSession, create: CreateUser) -> NoReturn:
#     create.password = jwt.get_hash_password(create.password)
#     new_user = User(**create.dict())
#     db.add(new_user)

async def create_user(db: AsyncSession, create: CreateUser) -> NoReturn:
    new_user = User(**create.dict())
    db.add(new_user)
    await db.commit()

async def create_user_from_auo(db: AsyncSession, loginid:str) -> NoReturn:
    res = login_by_powershell(loginid)
    if len(res.get('resData'))==0:
        return None
    user_info = res.get('resData')[0]
    await create_user(db,CreateUser(**user_info))


async def update_userinfo(db: AsyncSession, current_user: User, obj: UpdateUser) -> int:
    user = await db.execute(
        update(User)
        .where(User.id == current_user.id)
        .values(**obj.dict())
    )
    return user.rowcount


async def update_avatar(db: AsyncSession, current_user: User, avatar: str) -> int:
    user = await db.execute(
        update(User)
        .where(User.id == current_user.id)
        .values(avatar=avatar)
    )
    return user.rowcount


async def delete_user(db: AsyncSession, user_id: DeleteUser) -> int:
    user = await db.execute(delete(User).where(User.id == user_id))
    return user.rowcount


async def check_email(db: AsyncSession, email: str) -> User:
    mail = await db.execute(select(User).where(User.email == email))
    return mail.scalars().first()


async def delete_avatar(db: AsyncSession, user_id: int) -> int:
    user = await db.execute(
        update(User)
        .where(User.id == user_id)
        .values(avatar=None)
    )
    return user.rowcount


async def reset_password(db: AsyncSession, username: str, password: str) -> int:
    user = await db.execute(
        update(User)
        .where(User.username == username)
        .values(password=jwt.get_hash_password(password))
    )
    return user.rowcount


def get_users() -> Select:
    return select(User).order_by(desc(User.time_joined))


async def get_user_is_super(db: AsyncSession, user_id: int) -> bool:
    user = await get_task_by_id(db, user_id)
    return user.is_superuser


async def get_user_is_active(db: AsyncSession, user_id: int) -> bool:
    user = await get_task_by_id(db, user_id)
    return user.is_active


async def super_set(db: AsyncSession, user_id: int) -> int:
    super_status = await get_user_is_super(db, user_id)
    user = await db.execute(
        update(User)
        .where(User.id == user_id)
        .values(is_superuser=False if super_status else True)
    )
    return user.rowcount


async def active_set(db: AsyncSession, user_id: int) -> int:
    active_status = await get_user_is_active(db, user_id)
    user = await db.execute(
        update(User)
        .where(User.id == user_id)
        .values(is_active=False if active_status else True)
    )
    return user.rowcount



async def get_employees_by_boss_loginid(db: AsyncSession, boss_loginid: int)-> Optional[User]:
    user = await db.execute(select(User).where(User.boss_loginid == boss_loginid))
    return user.scalars().all()

